今天要來分享的是關於資料的觀測及設定。
首先這是我們的html資料,點一下對應的圖標,其圖標數字會加一。
<div class="title row ">
<div class="description col-12">
// 一般資料型態直接+即可
<div
class="badge badge-light"
@click="number++"
>
{{ number }}
</div>
</div>
<div class="description col-12 ">
// 純物件型態也是直接+即可
<div
class="badge badge-light"
@click="obj.num++"
>
{{ obj.num }}
</div>
</div>
<div class="description col-12 ">
// 而陣列中包物件資料型態,我們呼叫函數來做+
<div
v-for="(item,index) in objList"
class="badge badge-light"
@click="objListHandler(index)"
>
{{ item.num }}
</div>
</div>
<div class="description col-12">
// 陣列資料型態,我們呼叫函數來做+
<div
v-for="(number,index) in numberList"
class="badge badge-light"
@click="numberListHandler(index)"
>
{{ number }}
</div>
</div>
</div>
對應至data中的資料。
let data = {
number: 0,
obj: {
num: 0
},
objList: [{
num: 0
}, {
num: 0
}, {
num: 0
}],
numberList: [0, 0, 0]
}
而在method部分,先處理我們所呼叫用來做加總計算的函數。
首先為objList的部分,直接獲取對應下標的屬性(num)做++。
methods: {
{
objListHandler(index) {
this.objList[index].num++;
}
....
}
而在numberList的部分,我們使用像objList的方法直接獲取對應下標的資料做++,會發現畫面並沒有改變。
而我們可透過$vm0在console去抓Vue裡面的資料
。
可看出objList是一個observer的陣列,如果資料改動會被通知
// $vm0.objList(3)[{
// …}, {
// …}, {
// …}, __ob__: Observer]
可看出objList中下標0的資料是一個observer的物件,如果資料改動會被通知
// $vm0.objList[0] {
// __ob__: Observer
// }
可看出numberList是一個observer的陣列,如果資料改動會被通知
// $vm0.numberList(3)[1, 1, 1, __ob__: Observer]
但numberList中下標0的資料只是單純的值,所以資料改動並不會通知
,所以只會在下次通知要更新時,才會更新
// $vm0.numberList[0]
// 1
所以我們需透過vm.$set(target(目標物件或陣列), key(屬性), value(賦予的值))
動態新增響應式的屬性,且target本身將會進行通知。
numberListHandler(index) {
// 所以不可直接去改變陣列中的純值
// this.numberList[index]++;
this.$set(this.numberList, index, this.numberList[index] + 1)
}
對普通資料做觀測
watch: {
number(val, oldVal) {
console.log('number:', val, oldVal);
},
......
}
針對obj裡面某(單一)參數做觀測
// ["obj.xxx"]
["obj.num"](val, oldVal) {
console.log('obj:', val, oldVal);
}
針對obj所有資料做觀測,可發現舊的值及新值是相同,由於是對物件(或是陣列)做深度觀測,因為會指向原始物件本身
,所以結論在觀測的資料為物件,去觀測oldValue及value沒什麼意義,只會觀測到當前的值(Val)
,對於有物件型態皆要加上deep
。
obj: {
// 對整陀資料做function
handler(val, oldVal) {
console.log('obj.number:', val, oldVal)
// {__ob__: Observer} num: 1 ...
// {__ob__: Observer} num: 1 ...
},
// 我們改變的是objList中的物件,所以通知的是陣列中的物件,所以要加上deep,告訴vue 我們要觀測很深。
deep: true
},
對陣列做觀測,因為我們改變的是numberList中的資料,故通知的應當是其資料,但由於動態新增屬性的關係,是透過this.numberList通知,由於本身就會進行通知,故不需要再透過deep
。
numberList: {
handler(val, oldVal) {
console.log('numberList:', val, oldVal)
},
// deep: true
},